Esercitazione 5
Esercizio 5.1: esame 2023-07-18
Qui testo e soluzione.
Provare a svolgere da sé l'esercizio, prima di guardare la soluzione o andare oltre per la discussione.
Il corretto pilotaggio di interfacce parallele richiede inevitabilmente più stati di quanto è solito usare per esercizi, per esempio, con handshake dav_/rfd o soc/eoc.
Per questo, sono tipicamente gli esercizi che hanno più tempo a disposizione in sede d'esame.
In questo esercizio si lavora con interfacce parallele connesse a un bus, una interfaccia di ingresso con handshake (da cui ottenere dati in ingresso) e una interfaccia di ingresso e uscita senza handshake (a cui scrivere il risultato del calcolo). Il calcolo da svolgere è semplice: bisogna moltiplicare l'ingresso per 5, esprimendo il risultato su 16 bit. È opzionale sintetizzarlo con rete combinatoria.
La parte critica dell'esercizio è il corretto pilotaggio del bus, evitando corse critiche e usando potre tri-state per evitare situazioni di corto circuito, e delle interfacce.
Per quanto riguarda le operazioni sul bus, ricordiamo che le interfacce si attivano alla ricezione di segnali ior_
e iow_
.
Questi segnali arrivano a tutte le interfacce sul bus, ma è solo quella selezionata tramite addr
che si attiva, o leggendo data
o assegnandogli un valore.
È quindi critico che i fili di uscita addr
e data
siano stabili prima di portare ior_
o iow_
a 0.
Per data
, questo si traduce, per scritture, nel valore assegnato stabile (per esempio, con registro DATA
) e la porta tri-state abilitata (solitamente, DIR = 1
); per le letture invece si disabilita la porta tri-state (solitamente, DIR = 0
) per lasciare che sia l'interfaccia a assegnargli un valore.
Ricordiamo che il problema qui è di tipo elettrico: assegnare un valore logico a un filo equivale a imporre una tensione, e se più dispositivi assegnano tensioni diverse sullo stesso filo la differenza di potenziale porta a un disastroso corto circuito.
Questo schema di pilotaggio va ripetuto più volte per accedere ai diversi registri.
L'interfaccia parallela di ingresso con handshake richiede che si legga il suo registro RSR
, ed in particolare il suo flag FI
, in attesa che FI = 1
segnali la presenza di un dato da poter leggere.
La lettura verrà fatta sul registro RBR
.
Per l'interfaccia parallela di ingresso-uscita senza handshake, dovremo invece fare due scritture sul registro TBR
.
Esercizio 5.1: esame 2024-01-26
Qui testo e soluzione.
Provare a svolgere da sé l'esercizio, prima di guardare la soluzione o andare oltre per la discussione.
Il testo di questo esercizio è pensato per apparire fuori dalla norma a un occhio poco preparato, ma si rivela molto semplice con le dovute osservazioni.
Tralasciando le curiosità sulla congettura di Collatz, ciò che ci interessa è osservare che il calcolo di a partire da è di tipo combinatorio. Ciò è anche suggerito dal testo, che ci chiede di sintetizzare proprio questo.
Ciò che non è combinatorio è invece il calcolo di a partire da : questa è infatti una operazione iterativa, che implica una struttura ad anello che svolge più passaggi. Come dovremmo ben sapere, tali anelli non possono essere reti combinatorie, e vanno invece implementate con reti sincronizzate che avanzano a passaggi discreti guidati dal segnale del clock. Anche questa osservazione è suggerita dal testo, visto che il modo più immediato per ottenere è contare le iterazioni necessarie per arrivare ad 1.
La struttura chiave quindi è la seguente: abbiamo un registro N
che conterrà l'attuale , inizializzato con . Al posedge del clock, campionando l'uscita della rete combinatoria CALCOLO_ITERAZIONE
, riceve il nuovo valore .
Contemporaneamente, un registro K
, inizializzato a 0, conta con K <= K + 1;
quanti posedge sono necessari perché N
arrivi ad 1.
Questo è garantito dall'uso di un cambio di stato che interrompe il conteggio quando la condizione è raggiunta, fatte le solite osservazioni per il corretto conteggio di cicli di clock.
Questo ciclo può essere espresso come nel seguente pseudo-codice:
...
CALCOLO_ITERAZIONE ci(
.n_curr(N),
.n_next(n_next)
);
...
always @(posedge clock) if(reset_ == 1) #3 begin
casex(STAR)
...
S_init: begin
N <= n_0;
K <= 0;
...
end
S_loop: begin
N <= n_next;
K <= K + 1;
STAR <= (n_next == 1) ? S_after : S_loop;
end
S_after: ...
endcase
end
...
Una volta chiarito questo processo, il resto dell'esercizio è molto semplice.
Va dimensionato N
e la relativa rete combinatoria: il testo ci indica che il massimo raggiungibile è inferiore a 'h4000
, implicando che 14 bit sono sufficienti.
Va poi sintetizzata la rete combinatoria, che altro non è che un multiplexer, guidato dal bit meno significativo, i cui due ingressi sono uno shift a destra e un moltiplicatore con y = 3
e c = 1
.
Infine, la rete sincronizzata campiona n_0
e invia k
tramite un singolo handshake soc/eoc.